#pragma once

#include <cstdint>
#include <vector>
#include <functional>
#include <unordered_map>
#include "msp_protocol.h"

/**
 * MSP协议解析器
 * 用于解析和构造MSP协议的数据包
 */
class MSPParser {
 public:
  // 类型定义
  using FrameCallback = std::function<void(const MSP::Frame &)>;
  using AttitudeCallback = std::function<void(const MSP::AttitudeData &)>;
  using RawImuCallback = std::function<void(const MSP::RawImuData &)>;

  // 构造和析构
  MSPParser();
  ~MSPParser();

  // 解析接收到的数据
  void parse(const uint8_t *data, size_t size);
  void parse(const std::vector<uint8_t> &data);

  // 创建命令帧
  MSP::Frame createFrame(uint8_t command);
  MSP::Frame createFrame(uint8_t command, const std::vector<uint8_t> &payload);

  // 设置回调函数
  void setFrameCallback(FrameCallback callback);
  void setAttitudeCallback(AttitudeCallback callback);
  void setRawImuCallback(RawImuCallback callback);

  // 解析特定类型的数据
  MSP::AttitudeData parseAttitude(const MSP::Frame &frame) const;
  MSP::RawImuData parseRawImu(const MSP::Frame &frame) const;

  // 重置解析器状态
  void reset();

 private:
  // 协议解析状态
  MSP::FrameState state_;
  MSP::Frame currentFrame_;
  uint8_t expectedSize_;
  uint8_t readIndex_;

  // 回调函数
  FrameCallback frameCallback_;
  AttitudeCallback attitudeCallback_;
  RawImuCallback rawImuCallback_;

  // 处理完整的帧
  void handleFrame(const MSP::Frame &frame);

  // 辅助函数 - 从数据中提取有符号16位整数（小端序）
  int16_t read16(const std::vector<uint8_t> &buffer, size_t offset) const;

  // 辅助函数 - 从数据中提取无符号16位整数（小端序）
  uint16_t readU16(const std::vector<uint8_t> &buffer, size_t offset) const;

  // 辅助函数 - 从数据中提取有符号32位整数（小端序）
  int32_t read32(const std::vector<uint8_t> &buffer, size_t offset) const;

  // 辅助函数 - 将16位整数转换为字节（小端序）
  void write16(std::vector<uint8_t> &buffer, int16_t value);

  // 辅助函数 - 将32位整数转换为字节（小端序）
  void write32(std::vector<uint8_t> &buffer, int32_t value);
};